package awk.script.javassist.method04.proxy.bytebuddy;

import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;

import java.lang.reflect.Method;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @author yujianlong
 * @create 2021-03-29 17:20
 **/
public class TargetInterceptor {


	@RuntimeType
	public static Object intercept(@Origin Method method, @AllArguments Object[] objs, @SuperCall Callable<?> callable) throws Exception {
		long start = System.currentTimeMillis();
		Object resObj = null;
		try {
			resObj = callable.call();
			return resObj;
		} finally {

			int parameterCount = method.getParameterCount();

			Class<?>[] parameterTypes = method.getParameterTypes();

			String typeNames = IntStream.rangeClosed(0, parameterCount - 1).boxed().map(
					c -> parameterTypes[c].getTypeName()
			).collect(Collectors.joining(","));

//			String paraContent = Stream.of(objs).map(o -> JSONUtil.toJsonStr(o)).collect(Collectors.joining(","));
			String paraContent = Stream.of(objs).map(o -> Objects.toString(o)).collect(Collectors.joining(","));


			System.out.println("方法名称：" + method.getName());
			System.out.println("入参个数：" + method.getParameterCount());
			System.out.println("入参类型：" + typeNames);
			System.out.println("入参内容：" + paraContent);
			System.out.println("出参类型：" + method.getReturnType().getName());
			System.out.println("出参结果：" + resObj);
			System.out.println("方法耗时：" + (System.currentTimeMillis() - start) + "ms");
		}
	}
}
